接續上一篇的 annotation processor 實作,我們的 annotation processor 如果有需要分平台產生不同 parser 的話,可以利用 KAPT 的參數來讓使用者進行設定。舉例來說,我們現在要用 annotation processor 產生純 Kotlin 和 Android 的 parser ,這兩者內部的實作方式不太一樣,一個是用 DOM parser ,另一個是用 XmlPullParser
,這時候我們就可以定義 KAPT 的參數讓使用者做選擇。
kapt {
arguments {
arg("pureKotlinParser", true)
}
}
這個參數設定我們可以要求使用者加在使用到我們 library 的 module 下的 build.gradle
。之後我們可以在 processor 裡面拿到這個設定好的參數。
const val KAPT_OPTION_KEY = "pureKotlinParser"
@AutoService(Processor::class)
class RssAnnotationProcessor : AbstractProcessor() {
// 略
override fun process(typeElementSet: MutableSet<out TypeElement>?, roundEnvironment: RoundEnvironment?): Boolean {
val logger = Logger(processingEnv.messager)
val isPureKotlinParser = processingEnv.options[KAPT_OPTION_KEY]?.toBoolean() ?: false
if (isPureKotlinParser) {
generateClassesForKotlin(logger, roundEnvironment)
} else {
generateClassesForAndroid(logger, roundEnvironment)
}
return true
}
// 略
}
processingEnv 是 AbstractProcessor 提供的參數,讓我們可以拿到 processor 的環境變數和 logger 等。我們拿到 isPureKotlinParser 參數後,就可以決定我們要產生哪邊的程式碼了!
有了 processor 的結構,我們就要來處理 generator 。
因為我們要針對兩個平台產生不同的程式碼,這會先分成兩類:一種是專門處理 Parser 的程式碼 ParserGenerator
,另一種是 ExtensionGenerator
,專門產生 library 會用到的 extension function ,有點像是 util 類型的程式碼。Kotlin 和 Android 都各有自己的 generator ,比較特別的是 Android 這邊有多一個 AndroidReaderGenerator
,這個是因為在 Android 這邊還有幫忙載入和 快取 RSS 資料,這個類別是專門在產生 parser 產出結果後的對外接口程式碼。這些 parser 和 generator 各司其職,幫我們的 annotation processor 產生兩個平台的程式碼。